Skip to content

Fix dogfood detector edge cases#184

Merged
bomly-guy merged 2 commits into
mainfrom
codex/fix-dogfood-detectors
Jun 19, 2026
Merged

Fix dogfood detector edge cases#184
bomly-guy merged 2 commits into
mainfrom
codex/fix-dogfood-detectors

Conversation

@bomly-guy

@bomly-guy bomly-guy commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • make the Maven detector chmod Unix mvnw wrappers before execution, matching Gradle wrapper handling
  • use rootProject.name from Gradle settings files for the root package instead of Bomly temporary checkout directory names
  • skip the native SBT detector for old sbt projects where dependencyTree is unavailable unless sbt-dependency-graph is configured

Validation

  • go test ./internal/detectors/maven ./internal/detectors/gradle ./internal/detectors/sbt
  • go build -o /tmp/bomly-detectors-patched ./cmd/bomly

Summary by CodeRabbit

  • Bug Fixes

    • Maven wrapper scripts now correctly receive executable permissions on Unix systems when detected.
  • Improvements

    • Gradle detector now accurately identifies root project names by reading configuration from settings.gradle or settings.gradle.kts, improving dependency graph representation.
    • SBT detector enhanced to verify native analysis plugin availability before attempting native dependency detection.
  • Tests

    • Added comprehensive test coverage for Gradle root name detection, Maven wrapper permissions, and SBT plugin availability checks.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Three independent fixes across build-tool detectors: the Gradle detector reads rootProject.name from settings.gradle/settings.gradle.kts to name the root dependency-graph node; the Maven detector ensures mvnw wrapper files have executable bits set on Unix; and the SBT native detector checks whether the sbt-dependency-graph plugin is present before enabling native tree resolution for older sbt versions.

Changes

Gradle: root project name from settings files

Layer / File(s) Summary
gradleRootName helper and call site
internal/detectors/gradle/detector.go, internal/detectors/gradle/detector_test.go
Adds a compiled regex for rootProject.name = "...", introduces gradleRootName(workingDir) that reads settings.gradle or settings.gradle.kts with a filepath.Base fallback, updates runDependencies to pass the result into depGraphFromGradleOutput, and adds unit tests for the helper and an integration test asserting the graph root key uses the settings-derived name.

Maven: ensure mvnw is executable

Layer / File(s) Summary
ensureExecutableMavenWrapper and test
internal/detectors/maven/detector.go, internal/detectors/maven/detector_test.go
Adds ensureExecutableMavenWrapper (no-op on Windows; stat + os.Chmod(0o755) on Unix) called from wrapCommand, and a test that writes a non-executable mvnw, calls resolveRunner, and asserts executable bits are set.

SBT: gate native detector on dependency-graph plugin

Layer / File(s) Summary
NativeDetector.Applicable gating and helpers
internal/detectors/sbt/sbt_native.go, internal/detectors/sbt/detector_test.go
Expands Applicable to conditionally return false when the sbt version requires the sbt-dependency-graph plugin but none is found in project files; adds requiresDependencyGraphPlugin (reads project/build.properties, parses major/minor), hasDependencyGraphPlugin (scans plugin files for sbt-dependency-graph), and three tests covering old SBT without plugin, old SBT with plugin, and modern SBT.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • bomly-dev/bomly-cli#181: Adds fixture tests that call depGraphFromGradleOutput and assert graph node naming, directly related to this PR's change of how the root node name is derived and passed into that function.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes across all three detectors by referring to the edge cases being fixed in Maven, Gradle, and SBT dogfood detectors.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-dogfood-detectors

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Bomly Diff Summary

Compared 03abee7edbc2e2aceda9307d96345055280283b5 to f6a000c9f5bff873b2b686e821d35e3069edd66f.

Overview

Status Manifests Dependencies Findings Duration
✅ Pass +0 / ~0 / -0 +0 / ~0 / -0 0 introduced / 0 persisted / 0 resolved 64946ms

Dependency Changes

✅ No dependency changes.

Vulnerabilities

✅ No vulnerability changes.

License Changes

✅ No license changes.

Project Posture

✅ No project posture changes (or --matchers +scorecard was not selected).

Policy Findings

✅ No policy differences were identified.

@bomly-guy bomly-guy marked this pull request as ready for review June 19, 2026 09:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/detectors/sbt/sbt_native.go (1)

49-52: ⚡ Quick win

Use compact formatted DEBUG message for this two-value log.

At Line 49-52, this log uses two structured fields; your Go logging guideline prefers a compact fmt.Sprintf(...) message in that case.

Suggested change
-		d.logger().Debug("sbt native detector skipped: dependencyTree task is unavailable for this sbt version",
-			zap.String("working_dir", workingDir),
-			zap.String("sbt_version", sbtVersion(workingDir)),
-		)
+		d.logger().Debug(fmt.Sprintf(
+			"sbt native detector skipped: dependencyTree task is unavailable for this sbt version (working_dir=%s, sbt_version=%s)",
+			workingDir,
+			sbtVersion(workingDir),
+		))

As per coding guidelines, "Prefer compact one-line messages with fmt.Sprintf(...) for logs with one or two fields; prefer structured zap fields when a log carries several values or benefits from machine-readable context".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/detectors/sbt/sbt_native.go` around lines 49 - 52, The Debug log
statement in the sbt native detector is using structured zap fields for only two
values (working_dir and sbt_version). According to Go logging guidelines, logs
with one or two fields should use compact fmt.Sprintf formatted messages instead
of structured zap fields. Refactor the d.logger().Debug() call to embed the
workingDir and sbtVersion(workingDir) values directly into the message string
using fmt.Sprintf, removing the separate zap.String field parameters.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/detectors/gradle/detector_test.go`:
- Around line 233-237: Remove the inline fake Gradle binary creation code that
uses os.WriteFile to create the gradlePath fixture in this test. Instead,
integrate this Gradle script setup into the shared TestMain function fixture
setup in the test file (following the pattern used in
internal/cli/root_test_main_test.go for other fake binaries like npm and go),
then have the test reference the centralized fixture rather than creating it
locally. This ensures all fake binary setup for Gradle is consistent and
centralized in TestMain.

In `@internal/detectors/sbt/sbt_native.go`:
- Around line 162-173: The hasDependencyGraphPlugin function uses
strings.Contains to check for "sbt-dependency-graph" in the file content, which
matches both actual plugin declarations and commented-out text, causing false
positives. Instead of simple string matching, parse the file content more
carefully to identify only actual plugin declarations by checking for the proper
SBT syntax patterns (such as addSbtPlugin directives) rather than matching any
occurrence of the plugin name string. This will prevent commented-out or
incidental mentions from incorrectly triggering native mode enablement.

---

Nitpick comments:
In `@internal/detectors/sbt/sbt_native.go`:
- Around line 49-52: The Debug log statement in the sbt native detector is using
structured zap fields for only two values (working_dir and sbt_version).
According to Go logging guidelines, logs with one or two fields should use
compact fmt.Sprintf formatted messages instead of structured zap fields.
Refactor the d.logger().Debug() call to embed the workingDir and
sbtVersion(workingDir) values directly into the message string using
fmt.Sprintf, removing the separate zap.String field parameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3db4a184-d4da-44ec-a229-37f719e9d3ba

📥 Commits

Reviewing files that changed from the base of the PR and between 03abee7 and f6a000c.

📒 Files selected for processing (6)
  • internal/detectors/gradle/detector.go
  • internal/detectors/gradle/detector_test.go
  • internal/detectors/maven/detector.go
  • internal/detectors/maven/detector_test.go
  • internal/detectors/sbt/detector_test.go
  • internal/detectors/sbt/sbt_native.go

Comment on lines +233 to +237
gradlePath := filepath.Join(projectDir, "gradle-fixture")
script := "#!/bin/sh\ncat <<'OUT'\nruntimeClasspath - Runtime classpath of source set 'main'.\n\\--- org.springframework:spring-core:6.1.1\nOUT\n"
if err := os.WriteFile(gradlePath, []byte(script), 0o755); err != nil {
t.Fatalf("write gradle fixture: %v", err)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Move fake Gradle binary setup into shared TestMain fixtures.

Line 233-Line 237 create a fake Gradle executable inline; this should be centralized in the shared TestMain fake-binary setup to keep fixture behavior consistent across detector tests.

As per coding guidelines, "Fake binaries (npm, go, Gradle, plugin) must be built in TestMain — see internal/cli/root_test_main_test.go."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/detectors/gradle/detector_test.go` around lines 233 - 237, Remove
the inline fake Gradle binary creation code that uses os.WriteFile to create the
gradlePath fixture in this test. Instead, integrate this Gradle script setup
into the shared TestMain function fixture setup in the test file (following the
pattern used in internal/cli/root_test_main_test.go for other fake binaries like
npm and go), then have the test reference the centralized fixture rather than
creating it locally. This ensures all fake binary setup for Gradle is consistent
and centralized in TestMain.

Source: Coding guidelines

Comment on lines +162 to +173
func hasDependencyGraphPlugin(workingDir string) bool {
for _, name := range []string{
filepath.Join("project", "plugins.sbt"),
filepath.Join("project", "build.sbt"),
"build.sbt",
} {
raw, err := os.ReadFile(filepath.Join(workingDir, name))
if err != nil {
continue
}
if strings.Contains(string(raw), "sbt-dependency-graph") {
return true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Plugin detection is too broad and can false-positive on comments/text.

At Line 172, strings.Contains(..., "sbt-dependency-graph") treats any mention (including comments) as plugin presence, which can incorrectly keep native mode enabled for old SBT projects.

Suggested change
+var sbtDependencyGraphPluginDecl = regexp.MustCompile(`(?m)^\s*addSbtPlugin\([^)\n]*"sbt-dependency-graph"`)
+
 func hasDependencyGraphPlugin(workingDir string) bool {
 	for _, name := range []string{
 		filepath.Join("project", "plugins.sbt"),
 		filepath.Join("project", "build.sbt"),
 		"build.sbt",
 	} {
 		raw, err := os.ReadFile(filepath.Join(workingDir, name))
 		if err != nil {
 			continue
 		}
-		if strings.Contains(string(raw), "sbt-dependency-graph") {
+		if sbtDependencyGraphPluginDecl.Match(raw) {
 			return true
 		}
 	}
 	return false
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/detectors/sbt/sbt_native.go` around lines 162 - 173, The
hasDependencyGraphPlugin function uses strings.Contains to check for
"sbt-dependency-graph" in the file content, which matches both actual plugin
declarations and commented-out text, causing false positives. Instead of simple
string matching, parse the file content more carefully to identify only actual
plugin declarations by checking for the proper SBT syntax patterns (such as
addSbtPlugin directives) rather than matching any occurrence of the plugin name
string. This will prevent commented-out or incidental mentions from incorrectly
triggering native mode enablement.

@bomly-guy bomly-guy merged commit 1a5202f into main Jun 19, 2026
13 checks passed
@bomly-guy bomly-guy deleted the codex/fix-dogfood-detectors branch June 19, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant